package com.qianxun.spider.builder;

import com.qianxun.spider.bean.SpiderBean;
import com.qianxun.spider.bean.SpiderBeanField;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: huwei
 * @date: 2020/6/28 14:47
 * @version: 1.0.0
 */
public class SpiderBeanBuilder {

    private SpiderBean spiderBean;
    private List<SpiderBeanField> spiderBeanFieldList;

    private SpiderBeanBuilder(){
        this.spiderBean = new SpiderBean();
        this.spiderBeanFieldList = new ArrayList<>();
    }

    public static SpiderBeanBuilder newly(){
        return new SpiderBeanBuilder();
    }

    public SpiderBean buildClass(Class<?> cls){
        com.qianxun.spider.annote.SpiderBean spiderBeanAno = cls.getAnnotation(com.qianxun.spider.annote.SpiderBean.class);
        if(spiderBeanAno == null){
            throw new RuntimeException(cls.getName() + " ，没有标注：" + com.qianxun.spider.annote.SpiderBean.class.getName() + "注解");
        }
        SpiderBeanBuilder spiderBeanBuilder = SpiderBeanBuilder.newly().selector(spiderBeanAno.selector()).beanClass(cls);
        Field[] files = cls.getDeclaredFields();
        for(int i = 0 ;i < files.length ;++i){
            Field field = files[i];
            com.qianxun.spider.annote.SpiderBeanField spiderBeanFieldAno = field.getAnnotation(com.qianxun.spider.annote.SpiderBeanField.class);
            if(spiderBeanAno == null){
                continue;
            }
            SpiderBeanFieldBuilder spiderBeanFieldBuilder = spiderBeanBuilder.fieldBuilder().collection(spiderBeanFieldAno.collection()).selector(spiderBeanFieldAno.selector())
                    .fieldName(field.getName()).valueKey(spiderBeanFieldAno.valueKey()).collection(spiderBeanFieldAno.collection())
                    .setCurrentUrl(spiderBeanFieldAno.isSetCurrentUrl());
            if(spiderBeanFieldAno.addTaskUrl()){
                spiderBeanFieldBuilder.addTaskUrl();
            }
            if(spiderBeanFieldAno.postRequest()){
                spiderBeanFieldBuilder.postRequest();
            }
            if(!com.qianxun.spider.annote.SpiderBean.class.equals(spiderBeanFieldAno.spiderBeanClass())){
                spiderBeanFieldBuilder.spiderBean(buildClass(spiderBeanFieldAno.spiderBeanClass()));
            }
            spiderBeanFieldBuilder.buildFieldAndAdd();
        }
        return spiderBeanBuilder.build();
    }

    public SpiderBeanBuilder selector(String selector){
        this.spiderBean.setSelector(selector);
        return this;
    }

    public SpiderBeanBuilder collector(boolean collector){
        this.spiderBean.setCollector(collector);
        return this;
    }

    public SpiderBeanBuilder beanClass(Class<?> beanClass){
        this.spiderBean.setBeanClass(beanClass);
        return this;
    }

    public SpiderBeanFieldBuilder fieldBuilder(){
        return new SpiderBeanFieldBuilder(this);
    }

    public SpiderBean build(){
        if(this.spiderBeanFieldList.isEmpty()){
            throw new RuntimeException("字段信息不能为空");
        }
        this.spiderBean.setFieldList(this.spiderBeanFieldList);
        return this.spiderBean;
    }

    public class SpiderBeanFieldBuilder {
        private SpiderBeanBuilder spiderBeanBuilder;

        private SpiderBeanField spiderBeanField;

        public SpiderBeanFieldBuilder(SpiderBeanBuilder spiderBeanBuilder) {
            this.spiderBeanBuilder = spiderBeanBuilder;
            this.spiderBeanField = new SpiderBeanField();
        }

        public SpiderBeanFieldBuilder fieldName(String fieldName){
            this.spiderBeanField.setFieldName(fieldName);
            return this;
        }

        public SpiderBeanFieldBuilder spiderBean(SpiderBean spiderBean){
            this.spiderBeanField.setSpiderBean(spiderBean);
            return this;
        }

        public SpiderBeanFieldBuilder collection(boolean isCollection){
            this.spiderBeanField.setCollection(isCollection);
            return this;
        }

        public SpiderBeanFieldBuilder selector(String selector){
            this.spiderBeanField.setSelector(selector);
            return this;
        }

        public SpiderBeanFieldBuilder valueKey(String key){
            this.spiderBeanField.setValueKey(key);
            return this;
        }

        public SpiderBeanFieldBuilder addTaskUrl(){
            this.spiderBeanField.setAddTaskUrl(true);
            return this;
        }

        public SpiderBeanFieldBuilder postRequest(){
            this.spiderBeanField.setPostRequest(true);
            return this;
        }

        public SpiderBeanFieldBuilder url(boolean url){
            this.spiderBeanField.setUrl(url);
            return this;
        }

        public SpiderBeanFieldBuilder setCurrentUrl(boolean b){
            this.spiderBeanField.setSetCurrentUrl(b);
            return this;
        }

        public SpiderBeanBuilder buildFieldAndAdd(){
            if(this.spiderBeanField.getFieldName() == null){
                throw new RuntimeException("字段名不能为空");
            }
            if(this.spiderBeanField.getSpiderBean() == null && this.spiderBeanField.getSelector() == null){
                throw new RuntimeException("字段数据获取信息不能同时为空");
            }
            if(this.spiderBeanField.getSelector() != null && this.spiderBeanField.getValueKey() == null && this.spiderBeanField.getSpiderBean() == null){
                throw new RuntimeException("字段数据获取值方式不能为空");
            }
            this.spiderBeanBuilder.spiderBeanFieldList.add(this.spiderBeanField);
            return this.spiderBeanBuilder;
        }
    }
}
